#define DEBUG
using System;
using System.Diagnostics;
using System.Drawing;

namespace ICSharpCode.TextEditor.Document
{
	public class TextWord
	{
		public sealed class SpaceTextWord : TextWord
		{
			public override TextWordType Type => TextWordType.Space;

			public override bool IsWhiteSpace => true;

			public SpaceTextWord()
			{
				base.length = 1;
			}

			public SpaceTextWord(HighlightColor color)
			{
				base.length = 1;
				base.SyntaxColor = color;
			}

			public override Font GetFont(FontContainer fontContainer)
			{
				return null;
			}
		}

		public sealed class TabTextWord : TextWord
		{
			public override TextWordType Type => TextWordType.Tab;

			public override bool IsWhiteSpace => true;

			public TabTextWord()
			{
				base.length = 1;
			}

			public TabTextWord(HighlightColor color)
			{
				base.length = 1;
				base.SyntaxColor = color;
			}

			public override Font GetFont(FontContainer fontContainer)
			{
				return null;
			}
		}

		private HighlightColor color;

		private LineSegment line;

		private IDocument document;

		private int offset;

		private int length;

		private static TextWord spaceWord = new SpaceTextWord();

		private static TextWord tabWord = new TabTextWord();

		private bool hasDefaultColor;

		public static TextWord Space => TextWord.spaceWord;

		public static TextWord Tab => TextWord.tabWord;

		public int Offset => this.offset;

		public int Length => this.length;

		public bool HasDefaultColor => this.hasDefaultColor;

		public virtual TextWordType Type => TextWordType.Word;

		public string Word
		{
			get
			{
				if (this.document == null)
				{
					return string.Empty;
				}
				return this.document.GetText(this.line.Offset + this.offset, this.length);
			}
		}

		public Color Color
		{
			get
			{
				if (this.color == null)
				{
					return Color.Black;
				}
				return this.color.Color;
			}
		}

		public bool Bold
		{
			get
			{
				if (this.color == null)
				{
					return false;
				}
				return this.color.Bold;
			}
		}

		public bool Italic
		{
			get
			{
				if (this.color == null)
				{
					return false;
				}
				return this.color.Italic;
			}
		}

		public HighlightColor SyntaxColor
		{
			get
			{
				return this.color;
			}
			set
			{
				Debug.Assert(value != null);
				this.color = value;
			}
		}

		public virtual bool IsWhiteSpace => false;

		public static TextWord Split(ref TextWord word, int pos)
		{
			if (word.Type != 0)
			{
				throw new ArgumentException("word.Type must be Word");
			}
			if (pos <= 0)
			{
				throw new ArgumentOutOfRangeException("pos", pos, "pos must be > 0");
			}
			if (pos >= word.Length)
			{
				throw new ArgumentOutOfRangeException("pos", pos, "pos must be < word.Length");
			}
			TextWord result = new TextWord(word.document, word.line, word.offset + pos, word.length - pos, word.color, word.hasDefaultColor);
			word = new TextWord(word.document, word.line, word.offset, pos, word.color, word.hasDefaultColor);
			return result;
		}

		public virtual Font GetFont(FontContainer fontContainer)
		{
			return this.color.GetFont(fontContainer);
		}

		protected TextWord()
		{
		}

		public TextWord(IDocument document, LineSegment line, int offset, int length, HighlightColor color, bool hasDefaultColor)
		{
			Debug.Assert(document != null);
			Debug.Assert(line != null);
			Debug.Assert(color != null);
			this.document = document;
			this.line = line;
			this.offset = offset;
			this.length = length;
			this.color = color;
			this.hasDefaultColor = hasDefaultColor;
		}

		public override string ToString()
		{
			return "[TextWord: Word = " + this.Word + ", Color = " + this.Color.ToString() + "]";
		}
	}
}
